#!/usr/bin/perl -wc

package RFCMail::ESMTP::Server::ErrorPostponer;

use strict;
use RFCMail::ESMTP::Object::ForwardPath;


sub mail_from {
    my $self = shift;
    return (_postpone_error($self, 'MAIL', $self->SUPER::mail_from(@_)));
}


sub rcpt_to {
    my $self = shift;
    my ($to) = @_;
    return (_postpone_error($self, 'RCPT To:'.$to->forward_path, $self->SUPER::rcpt_to(@_)));
}


sub data_start {
    my $self = shift;
    return ($self->{state}->{postponed_error})
	if defined($self->{state}->{postponed_error});
    return ($self->SUPER::data_start(@_));
}


sub _postpone_error {
    my ($self, $comment, $result) = @_;
    return ($result)
	if exists($self->{postpone_error}) and not $self->{postpone_error};
    return ($result)
	if $result->[0] !~ /^[45]5/;
    my ($code, @text) = @$result;
    my $state = $self->{state};
    $state->{postponed_error} = [0, "Unable to continue due to previous error conditions:"]
	if not defined($state->{postponed_error});
    push @{$state->{postponed_error}},
	"Error $code postponed from '$comment'; text follows", map("  $_", @text);
    my $trans_code = ($code < 500) ? 451 : 554;
    $state->{postponed_error}->[0] = $trans_code
	if $trans_code > $state->{postponed_error}->[0];
    return ([250, "OK (error $code postponed until DATA)"]);
}


1;
